Skip to content

Comments

Fix inconsistent ISO timestamp formatting causing ValueError on step update#2798

Open
hztBUAA wants to merge 1 commit intoChainlit:mainfrom
hztBUAA:fix/timestamp-parsing-2491
Open

Fix inconsistent ISO timestamp formatting causing ValueError on step update#2798
hztBUAA wants to merge 1 commit intoChainlit:mainfrom
hztBUAA:fix/timestamp-parsing-2491

Conversation

@hztBUAA
Copy link
Contributor

@hztBUAA hztBUAA commented Feb 20, 2026

Summary

Fixes #2491

ChainlitDataLayer saves timestamps with a trailing Z (e.g., 2025-09-04T02:00:42.164000Z) via ISO_FORMAT, but reads them back using Python's .isoformat() which omits the Z (e.g., 2025-09-04T02:00:42.164000). When update_step calls create_step with the read-back createdAt string, strptime fails with:

ValueError: time data '2025-09-04T02:00:42.164000' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'

Changes

  • Add _parse_iso_datetime() helper that tolerates both with and without trailing Z
  • Add _datetime_to_utc_iso() helper that ensures all datetime-to-string conversions consistently include the trailing Z
  • Replace all bare .isoformat() calls with _datetime_to_utc_iso() across user, thread, and step serialization
  • Replace datetime.strptime(created_at, ISO_FORMAT) with _parse_iso_datetime(created_at) in create_step
  • Switch datetime.now() to datetime.utcnow() in get_current_timestamp() and update_thread() for correct UTC semantics
  • Add comprehensive tests covering parse/format roundtrip and step row conversion

Test plan

  • _parse_iso_datetime correctly parses both "...Z" and "..." formats
  • _datetime_to_utc_iso always produces strings ending with Z
  • Step row conversion produces Z-suffixed timestamps that can be re-parsed by create_step
  • None timestamps are preserved as None (not formatted)
  • Invalid formats still raise ValueError

Summary by cubic

Fix inconsistent ISO timestamp handling to prevent ValueError during step updates. Standardizes UTC timestamps with a trailing Z and makes parsing accept both formats.

  • Bug Fixes
    • Added tolerant ISO datetime parsing (with or without trailing Z).
    • Added UTC formatting helper that always appends Z; replaced isoformat/strptime usages across user, thread, and step serialization.
    • Switched to datetime.utcnow for current timestamps and thread updates.
    • Made element fields optional-safe and guarded storage read URL retrieval.
    • Added tests for parse/format roundtrip and step timestamp conversion.

Written for commit 9b70738. Summary will update on new commits.

…update

Timestamps were saved with trailing Z (UTC indicator) but read back via
.isoformat() without Z, causing a ValueError when update_step tried to
re-parse the createdAt string via strptime with the Z-requiring format.

Changes:
- Add _parse_iso_datetime() helper that handles both with/without Z
- Add _datetime_to_utc_iso() helper that ensures trailing Z on output
- Replace all .isoformat() calls with _datetime_to_utc_iso()
- Replace strptime(created_at, ISO_FORMAT) with _parse_iso_datetime()
- Switch datetime.now() to datetime.utcnow() for UTC consistency
- Add tests covering parse/format roundtrip and step row conversion

Fixes Chainlit#2491
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. data layer Pertains to data layers. labels Feb 20, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

@dokterbob dokterbob added review-me Ready for review! unit-tests Has unit tests. labels Feb 23, 2026
@dokterbob
Copy link
Collaborator

Would love to merge this, please run uv run ruff format over your code! :)

Copy link
Collaborator

@dokterbob dokterbob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great contrib! Please make requested fixups and ensure only code related to the problem at hand is in there! (E.g. stuff described in the PR description.)

If more changes are needed, knowing WHY is essential!


def test_parse_without_z_raises_on_bad_format(self):
"""Test that invalid format still raises ValueError."""
with pytest.raises(ValueError):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually correct, please add comment telling ruff to ignore this (explaining that it's the exception from underlying code).

mime=str(row["mime"]),
objectKey=str(row["objectKey"]),
mime=str(row["mime"]) if row.get("mime") else None,
objectKey=row.get("objectKey"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here seem unrelated to the problem at hand.

"Failed to get read URL for element '%s': %s",
elem.get("id", "unknown"),
e,
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it's a good idea to just log general Exception. This definitely should not be part of a fix regarding date time conversion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

data layer Pertains to data layers. review-me Ready for review! size:L This PR changes 100-499 lines, ignoring generated files. unit-tests Has unit tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Time are messed up in Chainlit

2 participants